import os, time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from bs4 import BeautifulSoup
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import pandas as pd
from datetime import datetime
from webdriver_manager.chrome import ChromeDriverManager
from selenium.common.exceptions import WebDriverException, TimeoutException
import random

def init_driver():
    try:
        # 使用 webdriver_manager 自动管理 ChromeDriver
        service = Service('./chromedriver/chromedriver')
        options = webdriver.ChromeOptions()
        # 基本设置
        options.add_argument('--start-maximized')
        options.add_argument('--disable-blink-features=AutomationControlled')
        options.add_argument('--disable-dev-shm-usage')
        options.add_argument('--no-sandbox')
        options.add_argument('--disable-gpu')
        options.add_argument('--disable-infobars')
        options.add_argument('--disable-notifications')
        
        # 设置更大的内存和缓存
        options.add_argument('--memory-pressure-off')
        options.add_argument('--disk-cache-size=1073741824')  # 1GB cache
        
        # 禁用不必要的扩展和功能
        options.add_argument('--disable-extensions')
        options.add_argument('--disable-default-apps')
        
        # 添加反检测设置
        options.add_experimental_option("excludeSwitches", ["enable-automation"])
        options.add_experimental_option('useAutomationExtension', False)
        
        # 设置页面加载策略为 EAGER，加快加载速度
        options.page_load_strategy = 'eager'
        
        # 设置 user-agent
        options.add_argument('user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36')
        
        driver = webdriver.Chrome(service=service, options=options)
        
        # 设置页面加载超时
        driver.set_page_load_timeout(30)
        driver.set_script_timeout(30)
        
        # 执行 CDP 命令来禁用 webdriver 标记
        driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
            'source': '''
                Object.defineProperty(navigator, 'webdriver', {
                    get: () => undefined
                })
            '''
        })
        
        return driver
    except WebDriverException as e:
        raise Exception(f"浏览器初始化失败: {str(e)}")
    except Exception as e:
        raise Exception(f"未知错误: {str(e)}")

def wait_for_login(driver, timeout=300):  # 5分钟超时
    try:
        driver.get("https://www.zhipin.com/web/user/?ka=header-login")
        # 等待登录成功标志
        WebDriverWait(driver, timeout).until(
            EC.presence_of_element_located((By.CLASS_NAME, "user-nav"))
        )
        time.sleep(2)  # 额外等待确保页面完全加载
        return True
    except TimeoutException:
        raise Exception("登录等待超时，请在5分钟内完成扫码登录")
    except Exception as e:
        raise Exception(f"登录过程发生错误: {str(e)}")

def safe_get_element_text(element, selector, default=""):
    """安全地获取元素文本"""
    try:
        el = element.select_one(selector)
        return el.text.strip() if el else default
    except Exception:
        return default

def get_job_description(driver, job_url):
    try:
        # 随机延时 1-3 秒
        time.sleep(random.uniform(1, 3))
        
        # 打开新标签页
        driver.execute_script(f"window.open('{job_url}', '_blank');")
        # 切换到新标签页
        driver.switch_to.window(driver.window_handles[-1])
        
        try:
            # 等待职位描述加载
            description_element = WebDriverWait(driver, 15).until(
                EC.presence_of_element_located((By.CLASS_NAME, "job-detail-section"))
            )
            description = description_element.text.strip()
        except TimeoutException:
            description = "获取超时"
        except Exception as e:
            description = f"获取失败: {str(e)}"
        
        # 关闭标签页并切回主页
        driver.close()
        driver.switch_to.window(driver.window_handles[0])
        
        return description
    except Exception as e:
        print(f"获取职位描述时出错: {str(e)}")
        # 确保切回主页面
        try:
            if len(driver.window_handles) > 1:
                driver.close()
            driver.switch_to.window(driver.window_handles[0])
        except:
            pass
        return "获取失败"

def apply_filters(driver, exp=None, scale=None):
    try:
        # 等待筛选按钮加载
        filter_buttons = WebDriverWait(driver, 15).until(
            EC.presence_of_all_elements_located((By.CLASS_NAME, "condition-item"))
        )
        
        # 工作经验筛选
        if exp and exp != '不限':
            for button in filter_buttons:
                if '经验' in button.text:
                    button.click()
                    time.sleep(random.uniform(1, 2))
                    exp_options = driver.find_elements(By.CSS_SELECTOR, '.condition-popup li')
                    for option in exp_options:
                        if exp in option.text:
                            option.click()
                            time.sleep(random.uniform(1, 2))
                            break
        
        # 公司规模筛选
        if scale and scale != '不限':
            for button in filter_buttons:
                if '规模' in button.text:
                    button.click()
                    time.sleep(random.uniform(1, 2))
                    scale_options = driver.find_elements(By.CSS_SELECTOR, '.condition-popup li')
                    for option in scale_options:
                        if scale in option.text:
                            option.click()
                            time.sleep(random.uniform(1, 2))
                            break
                            
        # 等待筛选结果加载
        time.sleep(3)
    except Exception as e:
        print(f"应用筛选条件时出错: {str(e)}")

def get_jobs(driver, keyword, city_code, exp=None, scale=None, limit=10):
    try:
        base_url = f"https://www.zhipin.com/web/geek/job?city={city_code}&query={keyword}"
        driver.get(base_url)
        
        # 等待职位列表加载完成
        WebDriverWait(driver, 15).until(
            EC.presence_of_element_located((By.CLASS_NAME, "job-card-wrapper"))
        )
        
        # 应用筛选条件
        apply_filters(driver, exp, scale)

        job_list = []
        page = 1
        jobs_processed = 0

        while jobs_processed < limit:
            soup = BeautifulSoup(driver.page_source, 'html.parser')
            jobs_on_page = soup.select('.job-card-wrapper')
            
            if not jobs_on_page:
                break
                
            for job in jobs_on_page:
                if jobs_processed >= limit:
                    break
                    
                try:
                    name = safe_get_element_text(job, '.job-name')
                    area = safe_get_element_text(job, '.job-area')
                    salary = safe_get_element_text(job, '.salary')
                    company = safe_get_element_text(job, '.company-name')
                    
                    # 获取公司详细信息
                    company_tags = job.select('.company-tag-list span')
                    company_info = [tag.text.strip() for tag in company_tags]
                    company_info = ' | '.join(company_info)
                    
                    # 获取职位标签
                    job_tags = job.select('.job-tag-list span')
                    job_requirements = [tag.text.strip() for tag in job_tags]
                    job_requirements = ' | '.join(job_requirements)
                    
                    url = "https://www.zhipin.com" + job.select_one('a')['href']
                    
                    # 获取职位描述
                    description = get_job_description(driver, url)
                    
                    job_list.append([
                        name, area, salary, company, company_info,
                        job_requirements, description, url
                    ])
                    
                    jobs_processed += 1
                    
                except Exception as e:
                    print(f"解析职位信息时出错: {str(e)}")
                    continue
            
            # 如果还需要更多数据，尝试翻页
            if jobs_processed < limit:
                try:
                    next_button = driver.find_element(By.CLASS_NAME, 'next')
                    if 'disabled' not in next_button.get_attribute('class'):
                        next_button.click()
                        time.sleep(random.uniform(2, 3))
                        page += 1
                    else:
                        break
                except:
                    break

        # 创建数据目录
        os.makedirs('data', exist_ok=True)
        
        # 使用更有意义的文件名
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
        filename = f'data/{keyword}_{city_code}_{timestamp}.csv'
        
        # 保存数据
        df = pd.DataFrame(job_list, columns=[
            '职位', '地区', '薪资', '公司', '公司信息',
            '职位要求', '职位描述', '链接'
        ])
        df.to_csv(filename, index=False, encoding='utf-8-sig')
        return filename
        
    except Exception as e:
        print(f"获取职位列表时出错: {str(e)}")
        raise e
